MySQL中的open_files_limit

open_files_limit 是mysql中的一个全局变量且不可动态修改。它控制着mysqld进程能使用的最大文件描述(FD)符数量。需要注意的是这个变量的值并不一定是你设定的值,mysqld会在系统允许的情况下尽量获取更多的FD数量。

首先我们看下官方文档的定义:

The number of files that the operating system permits mysqld to open. The value of this variable at
runtime is the real value permitted by the system and might be different from the value you specify at
server startup. The value is 0 on systems where MySQL cannot change the number of open files.

The effective open_files_limit value is based on the value specified at system startup (if any) and
the values of max_connections and table_open_cache, using these formulas:

1)10 + max_connections + (table_open_cache * 2)
2)max_connections * 5
3)open_files_limit value specified at startup, 5000 if none

mysqld在启动的时候,根据上述三种算法对该变量进行调整,并取三种算法中的最大值。也就是说最终确定的open_files_limit 可能比你设定的大,也可能小。
下面我们再瞅一眼源码(mysqld.cc):

 /**
   Adjust @c open_files_limit.
   Computation is  based on:
   - @c max_connections,
   - @c table_cache_size,
   - the platform max open file limit.
 */
 void adjust_open_files_limit(ulong *requested_open_files)
 {
   ulong limit_1;
   ulong limit_2;
   ulong limit_3;
   ulong request_open_files;
   ulong effective_open_files;
 
   /* MyISAM requires two file handles per table. */
   limit_1= 10 + max_connections + table_cache_size * 2;
 
   /*
     We are trying to allocate no less than max_connections*5 file
     handles (i.e. we are trying to set the limit so that they will
     be available).
   */
   limit_2= max_connections * 5;
 /* Try to allocate no less than 5000 by default. */
   limit_3= open_files_limit ? open_files_limit : 5000;
 
   request_open_files= max<ulong>(max<ulong>(limit_1, limit_2), limit_3);
 
   /* Notice: my_set_max_open_files() may return more than requested. */
   effective_open_files= my_set_max_open_files(request_open_files);
 //最终确定的值可能会比你设定的值大,也可能小。 如果小的话下面这段代码是打出两个警告信息。大的话当然没关系啦。
   if (effective_open_files < request_open_files)
   {
     if (open_files_limit == 0)
     {
       sql_print_warning("Changed limits: max_open_files: %lu (requested %lu)",
                         effective_open_files, request_open_files);
     }
     else
     {
       sql_print_warning("Could not increase number of max_open_files to "
                         "more than %lu (request: %lu)",
                         effective_open_files, request_open_files);
     }
   }
 
   open_files_limit= effective_open_files;
   if (requested_open_files)
     *requested_open_files= min<ulong>(effective_open_files, request_open_files);
 }

这段源码很容易看懂,注释很详细,官方文档的解释与源码也很相符。按照三种算法,算出三个limit值,最后取其中最大的一个去设定这个变量。通过源码我们也可以看到open_files_limit,table_open_cache,max_connections这几个参数是密切相关的。

open_files_limit这个参数应该在my.cnf中[mysqld_safe]中设定,因为mysqld_safe脚本读到这个变量会尝试执行ulimit -n 改变针对当前环境的FD limits. 然后在把这个变量传给mysqld,因此需要用root启动mysqld_safe,否则可能会无法修改成功(非root用户所使用的值不能超过hard limit). 如果只是在[mysqld]中指定这个变量,可能会受限于系统对默认的设置而无法生效。

[mysqld_safe]
core-file-size=10485760
open-files-limit=10000

启动后可以看到,这个变量作为参数传递给了mysqld

root     23344     1  0 11:16 pts/1    00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/dbfiles/mysql_home/data --socket=/dbfiles/mysql_home/data/mysql.sock --pid-file=/var/run/mysqld/mysqld.pid --basedir=/usr --user=mysql
mysql    24093 23344  0 11:29 pts/1    00:00:01 /usr/sbin/mysqld --basedir=/usr --datadir=/dbfiles/mysql_home/data --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/dbfiles/mysql_home/data/mysqld.err --open-files-limit=10000 --pid-file=/var/run/mysqld/mysqld.pid --socket=/dbfiles/mysql_home/data/mysql.sock --port=3306

查看该进程的FD limits. 发现已改变。

[root@stg-pxc-test01]/dbfiles:cat /proc/24093/limits
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            10485760             unlimited            bytes     
Max core file size        5368709120           5368709120           bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             31403                31403                processes 
Max open files            10000                10000                files     
Max locked memory         65536                65536                bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       31403                31403                signals   
Max msgqueue size         819200               819200               bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us      

我们再看下mysqld_safe的shell片段

if test -w / -o "$USER" = "root"
then
  if test "$user" != "root" -o $SET_USER = 1
  then
    USER_OPTION="--user=$user"
  fi
  # Change the err log to the right user, if it is in use
  if [ $want_syslog -eq 0 ]; then
    touch "$err_log"
    chown $user "$err_log"
  fi
  if test -n "$open_files"
  then
    ulimit -n $open_files
  fi
fi

if test -n "$open_files"
then
  append_arg_to_args "--open-files-limit=$open_files"
fi

由这段shell片段,我们可以看到,如果/目录不可写,或者用户不是root,设置文件描述符限制的操作就跳过去了。只有满足上面的判断条件,才会设置,并在设置完FD limits后,又把这个参数值通过--open-files-limit传给了mysqld.

CentOS 7使用了systemd管理进程,安装mysql时mysqld_safe不再被安装。若要配置open_file_limit可通过systemctl edit mysqld, 编辑service模块(或手工创建文件override.conf于目录/etc/systemd/system/mysqld.service.d下)。

[Service]
LimitNOFILE=max_open_files
PIDFile=/path/to/pid/file
Nice=nice_level
LimitCore=core_file_limit
Environment="LD_PRELOAD=/path/to/malloc/library"
Environment="TZ=time_zone_setting"

如此便可与mysqld_safe一样修改open_files_limit了.

阅读原文

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容